home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 18261 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.5 KB  |  114 lines

  1. Path: news.compuserve.com!newsmaster
  2. From: 76623,2065@compuserve.com  (Bobby Martin)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Here is my idea of callback code. However there are glitches can it be done better.
  5. Date: 19 Apr 1996 17:42:05 GMT
  6. Organization: CompuServe Incorporated
  7. Message-ID: <4l8j9d$781@arl-news-svc-3.compuserve.com>
  8. References: <Pine.SUN.3.91N2x.960418124921.4515B-100000@mumrik.nada.kth.se>
  9. Reply-To: 76623,2065@compuserve.com (Bobby Martin)
  10. NNTP-Posting-Host: dd35-197.compuserve.com
  11. X-Newsreader: IBM NewsReader/2 v1.03
  12.  
  13. In <Pine.SUN.3.91N2x.960418124921.4515B-100000@mumrik.nada.kth.se>, Fredrik Vhrstrvm <d92-foh@nada.kth.se> writes:
  14. >
  15. >How do people write callbacks? The following code captures what I want 
  16.  
  17. <snip>
  18.  
  19. Try this: create a base class for each signature of callback you desire which
  20. defines the interface to your callback function class (let's call it a functor).
  21. Then create a template child classes as needed to support various method
  22. signatures.  I'll give you an example of the use of this so as to entice you to
  23. read the rather lengthy batch of code I've tacked to the end of this post.
  24.  
  25. Before:
  26. typedef void (*VoidFunc)();
  27.  
  28. void setCallback( VoidFunc aFunc);
  29.  
  30. void hello();
  31.  
  32. void junk()
  33.     {
  34.     setCallback( hello);
  35.     ...
  36.     }
  37.  
  38. In this code, you can send in only C functions of signature 'void aFunc()'.  But
  39. with functors, the following is possible:
  40.  
  41. #include "voidfunc.hpp"
  42.  
  43. void setCallback( VoidFunc aFunc);
  44.  
  45. void hello();
  46.  
  47. SomeList<int> listOfInts;
  48.  
  49. void junk()
  50.     {
  51.     setCallback( VoidFunction( hello) );
  52.     ...
  53.     setCallback( VoidMemberFunc( listOfInts, SomeList<int>::add);
  54.     ...
  55.     }
  56.  
  57. Use this base class as the type for any argument through which you wish to
  58. pass a callback or other pointer to function.  
  59.  
  60. Note that I'm not purporting that these code fragments are examples of good
  61. C++ code, they're just examples of how to use the functors.  Due to a
  62. Borland bug, you will have to lose support for constant member functions
  63. under Borland by commenting out the constructor that takes a const member
  64. functions.
  65.  
  66. class VoidFunc        //base class for functors of signature 'void funcname();'
  67.     {
  68. public:
  69.     virtual void operator()() const =0;        // allows use of object like a function
  70.     const VoidFunc& operator*() const {return *this;}    //allows (*aFunc)() syntax
  71.     };
  72.  
  73. class VoidFunction : public VoidFunc
  74.     {
  75. private:
  76.     typedef void (*VdFunc) ();
  77.     VdFunc  myFunc;
  78. public:
  79.     VoidFunction( VdFunc aFunc = 0 ) : myFunc( aFunc ) {}
  80.     virtual void operator()() const { myFunc(); }
  81.     };
  82.  
  83. template <class T>
  84. class VoidMemberFunc : public VoidFunc
  85.     {
  86. private:
  87.     typedef void (T::*Tfunc)();
  88.     typedef void (T::*Tfuncc)() const;        //support for const member functions
  89.     const T*    myObjc;
  90.     T*          myObj;
  91.     Tfunc       myFunc;
  92.     Tfuncc      myFuncc;
  93. public:
  94.     VoidMemberFunc( const T& aObj, const Tfuncc& aFunc ) : myObj(0), myObjc( &aObj ), myFunc(0), myFuncc( aFunc ) {}    //comment this line out under Borland
  95.     VoidMemberFunc( T& aObj, const Tfunc& aFunc ) : myObjc(0), myObj( &aObj ), myFunc( aFunc ), myFuncc(0) {}
  96.     void function( const Tfunc& aFunc ) { myFunc = aFunc; }
  97.     void function( const Tfuncc& aFunc ) { myFuncc = aFunc; }
  98.     void object( const T& aObj ) { myObjc = &aObj; myObj = 0;}
  99.     void object( T& aObj ) { myObj = &aObj; myObjc = 0;}
  100.     inline virtual void operator()() const;
  101.     };
  102.  
  103. template <class T>
  104. void VoidMemberFunc<T>::operator()() const
  105.     {
  106.     if( myObj )
  107.         (myObj->*myFunc)();
  108.     else if( myObjc )
  109.         (myObjc->*myFuncc)();
  110.     }
  111.  
  112. Hope that helps,
  113. Bobby Martin
  114.